<?php

namespace app\admin\controller;

use app\common\controller\Adminbase;
use think\Loader;
use think\Request;

class Addons extends Adminbase
{
    /**
     * 显示资源列表
     *
     * @return \think\Response
     */
    public function index()
    {
        $list = get_addons_list();
        return view('index',['info'=>json_encode($list,JSON_UNESCAPED_UNICODE)]);
    }

    /**
     * 显示指定的资源
     *
     * @param  int  $id
     * @return \think\Response
     */
    public function read($id)
    {
        //
    }

    /**
     * 显示编辑资源表单页.
     *
     * @param \think\Request $request
     * @return \think\Response
     */
    public function edit(Request $request)
    {
        $name = request()->param('id');
        if(!$name){
            return json(['code'=>1,'msg'=>'数据错误，need ID']);
        }
        $ck_db = db('addons')->where('name',$name)->find();
        if(!$ck_db){
            return json(['code'=>1,'msg'=>'数据错误，插件未安装']);
        }
        $class = get_addons_class('Dailywords');
        if(!$class){
            return json(['code'=>1,'msg'=>'数据错误，实例化插件失败']);
        }
        $data = $ck_db['config'] ? json_decode($ck_db['config'],true) : [];
        $data['id'] = $ck_db['id'];
        $_class = new $class();
        $config = $_class->getConfig();
        foreach($config as $k=>$v){
            if(!isset($data[$v['field']]) || empty($data[$v['field']])){
                $data[$v['field']] = $v['value'];
            }
        }
        return view('public/edit',['filed'=>$config,'info'=>$data]);
    }

    /**
     * 保存更新的资源
     *
     * @param  \think\Request  $request
     * @return \think\Response
     */
    public function update(Request $request)
    {
        $data = $request->param();
        $verify = add_edit_verify($data,['id']);
        if($verify['code'] != 200){
            return json($verify);
        }
        $id = $data['id'];
        unset($data['id']);
        unset($data['file']);
        $config = json_encode($data,JSON_UNESCAPED_UNICODE);
        $info = [
            'id'=>$id,
            'config'=>$config,
        ];
        $res = $this->update_info('addons',$info);
        if($res['code'] == 200){
            session('mor_hooks',null);
        }
        return json($res);
    }
    public function install(Request $request){
        $name = $request->param('id');
        $ck_db = db('addons')->where('name',$name)->find();
        if($ck_db){
            return json(['code'=>1,'msg'=>'error:插件已安装']);
        }
        $class = get_addons_class($name);
        if(!$class){
            return json(['code'=>1,'msg'=>'数据错误，实例化插件失败']);
        }
        $_class = new $class();
        if(!method_exists($_class,'install')){
            return json(['code'=>1,'msg'=>'数据错误，插件预安装方法不存在']);
        }
        $addons_info = $_class->getInfo();
        if(!$addons_info || !$_class->checkInfo()){
            return json(['code'=>1,'msg'=>'error:插件信息缺失']);
        }
        $install = $_class->install();
        if(!$install){
            return json(['code'=>1,'msg'=>'error:插件预安装失败']);
        }
        $add_addons = $this->add_info('addons',$addons_info);
        if($add_addons['code'] == 200){
            $common = $this->hooks_addons_select($name);
            if($common){//存在待处理钩子数据
                foreach ($common as $hook) {
                    $_hooks = db('hooks')->where('name',$hook)->value('addons');
                    if($_hooks){
                        $_addons = explode(',',$_hooks);
                        $_addons = array_merge($_addons, $name);
                        $_addons = array_unique($_addons);
                    }else{
                        $_addons = [$name];
                    }
                    $update_hooks = db('hooks')->where('name',$hook)->update(['addons'=>implode(',',$_addons),"update_at"=>date('Y-m-d H:i:s')]);
                    if(!$update_hooks){
                        db('hooks')->where('name',$hook)->update(['addons'=>$_hooks,"update_at"=>date('Y-m-d H:i:s')]);//处理失败，数据恢复
                        return json(['code'=>1,'msg'=>'error:安装插件所挂载的钩子数据失败']);
                    }
                }
            }
            session('mor_hooks',null);
        }
        return json($add_addons);
    }
    public function uninstall(Request $request){
        $name = $request->param('id');
        $ck_db = db('addons')->where('name',$name)->find();
        if(!$ck_db){
            return json(['code'=>1,'msg'=>'error:插件未安装']);
        }
        $class = get_addons_class($name);
        if(!$class){
            return json(['code'=>1,'msg'=>'数据错误，实例化插件失败']);
        }
        $_class = new $class();
        if(!method_exists($_class,'uninstall')){
            return json(['code'=>1,'msg'=>'数据错误，插件预卸载方法不存在']);
        }
        $uninstall = $_class->uninstall();
        if(!$uninstall){
            return json(['code'=>1,'msg'=>'error:插件预卸载失败']);
        }
        $common = $this->hooks_addons_select($name);
        if($common){//存在待处理钩子数据
            foreach ($common as $hook) {
                $_hooks = db('hooks')->where('name',$hook)->value('addons');
                if($_hooks){
                    $_addons = explode(',',$_hooks);
                    $new_addons = array_diff($_addons, [$name]);
                    $update_hooks = db('hooks')->where('name',$hook)->update(['addons'=>implode(',',$new_addons),"update_at"=>date('Y-m-d H:i:s')]);
                    if(!$update_hooks){
                        db('hooks')->where('name',$hook)->update(['addons'=>$_hooks,"update_at"=>date('Y-m-d H:i:s')]);//处理失败，数据恢复
                        return json(['code'=>1,'msg'=>'error:卸载插件所挂载的钩子数据失败']);
                    }
                }
            }
        }
        session('mor_hooks',null);
        $delete_addons = db('addons')->where('name',$name)->delete();
        if($delete_addons){
            return json(['code'=>200,'msg'=>'插件卸载成功']);
        }else{
            return json(['code'=>1,'msg'=>'插件卸载失败']);
        }
    }
    public function addons_update(Request $request){
        $name = $request->param('id');
        $ck_db = db('addons')->where('name',$name)->find();
        if(!$ck_db){
            return json(['code'=>1,'msg'=>'error:插件未安装']);
        }
        $class = get_addons_class($name);
        if(!$class){
            return json(['code'=>1,'msg'=>'数据错误，实例化插件失败']);
        }
        $_class = new $class();
        if(!method_exists($_class,'update')){
            return json(['code'=>1,'msg'=>'数据错误，插件更新方法不存在']);
        }
        $update = $_class->update();
        if($update){
            session('mor_hooks',null);
            return json(['code'=>200,'msg'=>'插件更新成功,若未更新,请重新安装']);
        }else{
            return json(['code'=>200,'msg'=>'插件更新失败']);
        }
    }
    public function set_status(Request $request){
        $data = $request->param();
        $verify = add_edit_verify($data,['name','state']);
        if($verify['code'] != 200){
            return json($verify);
        }
        $old = db('addons')->where('name',$data['name'])->find();
        if(!$old){
            return json(['code'=>1,'msg'=>'插件不存在/或未安装']);
        }
        if($old['status'] == 1){
            $data['state'] = 2;
        }else{
            $data['state'] = 1;
        }
        $info = [
          'id'=>$old['id'],
          'status'=>$data['state'],
        ];
        $res = $this->update_info('addons',$info);
        if($res['code'] == 200){
            session('mor_hooks',null);
        }
        return json($res);
    }
    public function upload_addons(Request $request){
        $file = $request->file('addons');
        if($file){
            $file_info = $file->getInfo();
            $res = mor_addons_unzip($file_info['tmp_name']);
            if($res){
                return json(['code'=>200,'msg'=>'上传成功!']);
            }else{
                return json(['code'=>1,'msg'=>'上传失败!']);
            }
        }
    }
    /**
     * 删除指定资源
     *
     * @param  int  $id
     * @return \think\Response
     */
    public function delete($id)
    {
        //
    }
    public function execute()
    {
        $_addons = request()->param('_addons');
        $_controller = request()->param('_controller');
        $_action = request()->param('_action');
        if (!empty($_addons) && !empty($_controller) && !empty($_action)) {
            // 获取类的命名空间
            $class = get_addons_class($_addons, 'controller', $_controller);
            if (class_exists($class)) {
                $model = new $class();
                if ($model === false) {
                    abort(500, lang('addon init fail'));
                }
                return call_user_func_array([$model, $_action], [$this->request]);
            } else {
                abort(500, lang('Controller Class Not Exists'));
            }
        }
        abort(500, lang('addon cannot name or action'));
    }
    public function hooks_addons_select($name){
        if($name){
            $class = get_addons_class($name);
            $methods = get_class_methods($class);
            $methods = delete_addons_methods($methods);
            $hooks = db('hooks')->column('name');
            $case = config('url_convert');
            foreach($methods as $k=>$v){
                $methods[$k] = $case ? Loader::parseName($v) : $v;
            }
            return array_intersect($hooks, $methods);
        }else{
            return [];
        }
    }
}
